home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
network
/
samba
/
patches
/
samba-1.032
/
samba-1
Wrap
Text File
|
1995-09-10
|
66KB
|
2,045 lines
diff -u -r --new-file last-version/docs/ENCRYPTION.txt samba-1.9.14alpha13/docs/ENCRYPTION.txt
--- last-version/docs/ENCRYPTION.txt Tue Jul 11 22:37:36 1995
+++ samba-1.9.14alpha13/docs/ENCRYPTION.txt Mon Sep 11 00:11:55 1995
@@ -1,3 +1,256 @@
+ LanManager / Samba Password Encryption.
+ ---------------------------------------
+
+With the development of LanManager compatible password encryption for
+Samba, it is now able to validate user connections in exactly the same
+way as a LanManager or Windows NT server.
+
+This document describes how the SMB password encryption algorithm
+works and what issues there are in choosing whether you want to use
+it. You should read it carefully, especially the part about security
+and the "PROS and CONS" section.
+
+How does it work ?
+------------------
+
+ LanManager encryption is somewhat similar to UNIX password
+encryption. The server uses a file containing a hashed value of a
+users password. This is created by taking the users paintext
+password, capitalising it, and either truncating to 14 bytes (or
+padding to 14 bytes with null bytes). This 14 byte value is used as
+two 56 bit DES keys to encrypt a 'magic' eight byte value, forming a
+16 byte value which is stored by the server and client. Let this value
+be known as the *hashed password*.
+
+When a client (LanManager, Windows for WorkGroups, Windows 95 or
+Windows NT) wishes to mount a Samba drive (or use a Samba resource) it
+first requests a connection and negotiates the protocol that the client
+and server will use. In the reply to this request the Samba server
+generates and appends an 8 byte, random value - this is stored in the
+Samba server after the reply is sent and is known as the *challenge*.
+
+The challenge is different for every client connection.
+
+The client then uses the hashed password (16 byte value described
+above), appended with 5 null bytes, as three 56 bit DES keys, each of
+which is used to encrypt the challenge 8 byte value, forming a 24 byte
+value known as the *response*.
+
+In the SMB call SMBsessionsetupX (when user level security is
+selected) or the call SMBtconX (when share level security is selected)
+the 24 byte response is returned by the client to the Samba server.
+
+The Samba server then reproduces the above calculation, using it's own
+stored value of the 16 byte hashed password (read from the smbpasswd
+file - described later) and the challenge value that it kept from the
+negotiate protocol reply. It then checks to see if the 24 byte value it
+calculates matches the 24 byte value returned to it from the client.
+
+If these values match exactly, then the client knew the correct
+password (or the 16 byte hashed value - see security note below) and
+is this allowed access. If not then the client did not know the
+correct password and is denied access.
+
+Note that the Samba server never knows or stores the cleartext of the
+users password - just the 16 byte hashed function derived from it. Also
+note that the cleartext password or 16 byte hashed value are never
+transmitted over the network - thus increasing security.
+
+IMPORTANT NOTE ABOUT SECURITY
+-----------------------------
+
+The unix and SMB password encryption techniques seem similar on the
+surface. This similarity is, however, only skin deep. The unix scheme
+typically sends clear text passwords over the nextwork when logging
+in. This is bad. The SMB encryption scheme never sends the cleartext
+password over the network but it does store the 16 byte hashed value
+on disk. This is also bad. Why? Because the 16 byte hashed value is a
+"password equivalent". You cannot derive the users password from it,
+but it could potentially be used in a modified client to gain access
+to a server. This would require considerable technical knowledge on
+behalf of the attacker but is perfectly possible. You should thus
+treat the smbpasswd file as though it contained the cleartext
+passwords of all your users. Its contents must be kept secret, and the
+file should be protected accordingly.
+
+Ideally we would like a password scheme which neither requires plain
+text passwords on the net or on disk. Unfortunately this is not
+available as Samba is stuck with being compatible with other SMB
+systems (WinNT, WfWg, Win95 etc).
+
+
+PROS AND CONS
+-------------
+
+There are advantages and disadvantages to both schemes.
+
+Advantages of SMB Encryption:
+-----------------------------
+
+- plain text passwords are not passed across the network. Someone using
+a network sniffer cannot just record passwords going to the SMB server.
+
+- WinNT doesn't like talking to a server that isn't using SMB
+encrypted passwords. It will refuse to browse the server if the server
+is also in user level security mode. It will insist on promting the
+user for the password on each connection, which is very annoying. The
+only things you can do to stop this is to use SMB encryption.
+
+Advantages of non-encrypted passwords:
+--------------------------------------
+
+- plain text passwords are not kept on disk.
+
+- uses same password file as other unix services such as login and
+ftp
+
+- you are probably already using other services (such as telnet and
+ftp) which send plain text passwords over the net, so not sending them
+for SMB isn't such a big deal.
+
+- the SMB encryption code in Samba is new and has only had limited
+testing. We have tried hard to make it secure but in any new
+implementation of a password scheme there is the possability of an
+error.
+
+
+The smbpasswd file.
+-------------------
+
+ In order for Samba to participate in the above protocol it must
+be able to look up the 16 byte hashed value given a user name.
+Unfortunately, as the UNIX password value is also a one way hash
+function (ie. it is impossible to retrieve the cleartext of the users
+password given the UNIX hash of it) then a separate password file
+containing this 16 byte value must be kept. To minimise problems with
+these two password files, getting out of sync, the UNIX /etc/passwd and
+the smbpasswd file, a utility, mksmbpasswd.sh, is provided to generate
+a smbpasswd file from a UNIX /etc/passwd file.
+
+To generate the smbpasswd file from your /etc/passwd file use the
+following command :-
+
+cat /etc/passwd | mksmbpasswd.sh >/usr/local/samba/private/smbpasswd
+
+If you are running on a system that uses NIS, use
+
+ypcat passwd | mksmbpasswd.sh >/usr/local/samba/private/smbpasswd
+
+The mksmbpasswd.sh program is found in the Samba source directory. By
+default, the smbpasswd file is stored in :-
+
+/usr/local/samba/private/smbpasswd
+
+The owner of the /usr/local/samba/private directory should be set to
+root, and the permissions on it should be set to :-
+
+r-x------
+
+The command
+
+chmod 500 /usr/local/samba/private
+
+will do the trick. Likewise, the smbpasswd file inside the private
+directory should be owned by root and the permissions on is should be
+set to
+
+rw-------
+
+by the command :-
+
+chmod 600 smbpasswd.
+
+The format of the smbpasswd file is
+
+username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Long name:user home dir:user shell
+
+Although only the username, uid, and XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+sections are significant and are looked at in the Samba code.
+
+It is *VITALLY* important that there by 32 'X' characters between the
+two ':' characters - the smbpasswd and Samba code will fail to validate
+any entries that do not have 32 characters between ':' characters.
+
+When the password file is created all users have password entries
+consisting of 32 'X' characters. By default this disallows any access
+as this user. When a user has a password set, the 'X' characters change
+to 32 ascii hexadecimal digits (0-9, A-F). These are an ascii
+representation of the 16 byte hashed value of a users password.
+
+To set a user to have no password (not recommended), edit the file
+using vi, and replace the first 11 characters with the asci text
+
+NO PASSWORD
+
+Eg. To clear the password for user bob, his smbpasswd file entry would
+look like :
+
+bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:Bob's full name:/bobhome:/bobshell
+
+If you are allowing users to use the smbpasswd command to set their own
+passwords, you may want to give users NO PASSWORD initially so they do
+not have to enter a previous password when changing to their new
+password (not recommended).
+
+Note : This file should be protected very carefully. Anyone with
+access to this file can (with enough knowledge of the protocols) gain
+access to your SMB server. The file is thus more sensitive than a
+normal unix /etc/passwd file.
+
+The smbpasswd Command.
+----------------------
+
+ The smbpasswd command maintains the 32 byte password field in
+the smbpasswd file. If you wish to make it similar to the unix passwd
+or yppasswd programs, install it in /usr/local/samba/bin (or your main
+Samba binary directory) and make it setuid root.
+
+Note that if you do not do this then the root user will have to set all
+users passwords.
+
+To set up smbpasswd as setuid root, change to the Samba binary install
+directory and then type (as root) :
+
+chown root smbpasswd
+chmod 4555 smbpasswd
+
+If smbpasswd is installed as setuid root then you would use it as
+follows.
+
+smbpasswd
+Old SMB password: <type old alue here - just hit return if there is NO PASSWORD>
+New SMB Password: < type new value >
+Repeat New SMB Password: < re-type new value >
+
+If the old value does not match the current value stored for that user,
+or the two new values do not match each other, then the password will
+not be changed.
+
+If invoked by an ordinary user it will only allow the user to change
+his or her own Samba password.
+
+If run by the root user smbpasswd may take an optional argument,
+specifying the user name whose SMB password you wish to change. Note
+that when run as root smbpasswd does not prompt for or check the old
+password value, thus allowing root to set passwords for users who have
+forgotten their passwords.
+
+smbpasswd is designed to work in the same way and be familiar to UNIX
+users who use the passwd or yppasswd commands.
+
+NOTE. As smbpasswd is designed to be installed as setuid root I would
+appreciate it if everyone examined the source code to look for
+potential security flaws. A setuid program, if not written properly can
+be an open door to a system cracker. Please help make this program
+secure by reporting all problems to me (the author, Jeremy Allison).
+
+My email address is :-
+
+jra@vantive.com
+
+Setting up Samba to support LanManager Encryption.
+--------------------------------------------------
+
This is a very brief description on how to setup samba to support
password encryption. More complete instructions will probably be added
later.
@@ -7,19 +260,40 @@
2) enable the encryption stuff in the Samba makefile, making sure you
point it to the libdes library and include file (it needs des.h)
+The entries you need to uncomment are the four lines after the comment :-
+
+# This is for SMB encrypted (lanman) passwords.
+
+Note that you may have to change the variable DES_BASE to
+point at the place where you installed the DES library.
3) compile and install samba as usual
-4) enable encrypted passwords in smb.conf by adding the line
+4) f your system can't compile the module getsmbpass.c then remove the
+-DSMBGETPASS define from the Makefile.
+
+5) enable encrypted passwords in smb.conf by adding the line
"encrypt passwords = yes" in the [global] section
-5) create the initial smbpasswd password file in the place you
+6) create the initial smbpasswd password file in the place you
specified in the Makefile. A simple way to do this based on your
existing Makefile (assuming it is in a reasonably standard format) is
like this:
cat /etc/passwd | mksmbpasswd.sh > /usr/local/samba/private/smbpasswd
+Change ownership of private and smbpasswd to root.
+
+chown -R root /usr/local/samba/private
+
+Set the correct permissions on /usr/local/samba/private
+
+chmod 500 /usr/local/samba/private
+
+Set the correct permissions on /usr/local/samba/private/smbpasswd
+
+chmod 600 /usr/local/samba/private/smbpasswd
+
note that the mksmbpasswd.sh script is in the samba source directory.
If this fails then you will find that you will need entries that look
@@ -28,13 +302,32 @@
# SMB password file.
tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Andrew Tridgell:/home/tridge:/bin/tcsh
-note that the uid and username fields must be right. Also try to get
+note that the uid and username fields must be right. Also, you must get
the number of X's right (there should be 32).
-6) set the passwords for users using the smbpasswd command. For
+If you wish, install the smbpasswd program as suid root.
+
+chown root /usr/local/samba/bin/smbpasswd
+chmod 4555 /usr/local/samba/bin/smbpasswd
+
+7) set the passwords for users using the smbpasswd command. For
example, as root you could do "smbpasswd tridge"
-7) try it out!
+8) try it out!
Note that you can test things using smbclient, as it also now supports
encryption.
+
+NOTE TO USA Sites that Mirror Samba
+-----------------------------------
+
+The DES library is considered a munition in the USA. Under US Law it is
+illegal to export this software, or to put it in a freely available ftp
+site.
+
+Please do not mirror the DES directory from the site on nimbus.anu.edu.au
+
+Thank you,
+
+Jeremy Allison.
+
diff -u -r --new-file last-version/docs/THANKS samba-1.9.14alpha13/docs/THANKS
--- last-version/docs/THANKS Fri Jun 23 20:55:51 1995
+++ samba-1.9.14alpha13/docs/THANKS Sun Sep 3 11:41:21 1995
@@ -18,16 +18,30 @@
Lee Fisher (leefi@microsoft.com)
+Charles Fox (cfox@microsoft.com)
+Dan Perry (danp@exchnge.microsoft.com)
+ These Microsoft people have been very helpful and supportive of
+ the development of Samba.
+
Lee very kindly supplied me with a copy of the X/Open SMB
specs. These have been invaluable in getting the details of the
implementation right. They will become even more important as we move
towards a Lanman 2.1 compliant server. Lee has provided very
useful advice on several aspects of the server.
-
Lee has also provided me with copies of Windows NTAS 3.1, Visual C
- and a developers CD-ROM. Being able to run NT at home will be a
+ and a developers CD-ROM. Being able to run NT at home is a
great help.
+
+ Charles has helped out in numerous ways with the provision of SMB
+ specifications and helpful advice. He has been following the
+ discussion of Samba on the mailing list and has stepped in
+ regularly to clarify points and to offer help.
+
+ Dan has put me in touch with NT developers to help sort out bugs and
+ compatability issues. He has also supplied me with a copy of the
+ NT browsing spec, which will help a lot in the development of the
+ Samba browser code.
Bruce Perens (bruce@pixar.com)
diff -u -r --new-file last-version/source/Makefile samba-1.9.14alpha13/source/Makefile
--- last-version/source/Makefile Sat Sep 2 14:23:31 1995
+++ samba-1.9.14alpha13/source/Makefile Sun Sep 10 23:26:09 1995
@@ -88,7 +88,7 @@
# DES_BASE=/usr/local/libdes
# DES_FLAGS= -I$(DES_BASE)
# DES_LIB= -L$(DES_BASE) -ldes
-# PASSWD_FLAGS=-DSMB_PASSWD -DSMB_PASSWD_FILE=\"$(BASEDIR)/private/smbpasswd\"
+# PASSWD_FLAGS=-DSMB_PASSWD -DSMBGETPASS -DSMB_PASSWD_FILE=\"$(BASEDIR)/private/smbpasswd\"
#####################################
# WHICH OPERATING SYSTEM?
@@ -465,9 +465,9 @@
@echo Linking testprns
@$(CC) $(CFLAGS) -o testprns testprns.o $(PARAMOBJ) $(LIBS)
-smbpasswd: smbpasswd.o $(PARAMOBJ)
+smbpasswd: smbpasswd.o getsmbpass.o $(PARAMOBJ)
@echo Linking smbpasswd
- @$(CC) $(CFLAGS) -o smbpasswd smbpasswd.o $(PARAMOBJ) $(LIBS)
+ @$(CC) $(CFLAGS) -o smbpasswd getsmbpass.o smbpasswd.o $(PARAMOBJ) $(LIBS)
install: installbin installman
diff -u -r --new-file last-version/source/change-log samba-1.9.14alpha13/source/change-log
--- last-version/source/change-log Sat Sep 2 17:47:16 1995
+++ samba-1.9.14alpha13/source/change-log Mon Sep 11 00:14:27 1995
@@ -1535,6 +1535,11 @@
- trim_string patch from J.W.Schilperoort@research.ptt.nl
- fixed problem with files with no extension getting mixed up
- ipc bugfix for print job deletion from Rainer Leberle <rleberle@auspex.de>
+ - released alpha12
+ - pwlen fix in NETGROUP from Andrew J Cole <A.J.Cole@cbl.leeds.ac.uk>
+ - lots of uid and encryption changes from Jeremy Allison. WinDD
+ should now work.
+ - released alpha13
==========
diff -u -r --new-file last-version/source/getsmbpass.c samba-1.9.14alpha13/source/getsmbpass.c
--- last-version/source/getsmbpass.c Thu Jan 1 10:00:00 1970
+++ samba-1.9.14alpha13/source/getsmbpass.c Sun Sep 10 23:28:46 1995
@@ -0,0 +1,167 @@
+#if (defined(SMB_PASSWD) && defined(SMBGETPASS))
+
+/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+/* Modified to use with samba by Jeremy Allison, 8th July 1995. */
+
+#ifdef SUNOS4
+#define _sys_ioctl_h
+#endif
+
+#ifdef SUNOS5
+#define _SYS_IOCTL_H
+#endif
+
+#include "includes.h"
+
+#include <termios.h>
+
+#ifdef SYSV_TERMIO
+
+/* SYSTEM V TERMIO HANDLING */
+
+static struct termio t;
+
+#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
+#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
+#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
+
+#ifndef TCSAFLUSH
+#define TCSAFLUSH 1
+#endif
+
+int tcgetattr(int fd, struct termio *t)
+{
+ return ioctl(fd, TCGETA, t);
+}
+
+int tcsetattr(int fd, int flags, const struct termio *t)
+{
+ if(flags & TCSAFLUSH)
+ ioctl(fd, TCFLSH, TCIOFLUSH);
+ return ioctl(fd, TCSETS, t);
+}
+
+#elif BSD_TERMIO
+
+/* BSD TERMIO HANDLING */
+
+static struct sgttyb t;
+
+#define ECHO_IS_ON(t) ((t).sg_flags & ECHO)
+#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO)
+#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO)
+
+#ifndef TCSAFLUSH
+#define TCSAFLUSH 1
+#endif
+
+int tcgetattr(int fd, struct sgttyb *t)
+{
+ return ioctl(fd, TIOCGETP, (char *)t);
+}
+
+int tcsetattr(int fd, int flags, const struct sgttyb *t)
+{
+ return ioctl(fd, TIOCSETP, (char *)t);
+}
+
+#else
+
+/* POSIX TERMIO HANDLING */
+#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
+#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
+#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
+
+static struct termios t;
+#endif
+
+char *
+getsmbpass (prompt)
+ const char *prompt;
+{
+ FILE *in, *out;
+ int echo_off;
+ static char buf[256];
+ static size_t bufsize = sizeof(buf);
+ size_t nread;
+
+ /* Catch problematic signals */
+ signal(SIGINT, SIGNAL_CAST SIG_IGN);
+
+ /* Try to write to and read from the terminal if we can.
+ If we can't open the terminal, use stderr and stdin. */
+
+ in = fopen ("/dev/tty", "w+");
+ if (in == NULL)
+ {
+ in = stdin;
+ out = stderr;
+ }
+ else
+ out = in;
+
+ setvbuf(in, NULL, _IONBF, 0);
+
+ /* Turn echoing off if it is on now. */
+
+ if (tcgetattr (fileno (in), &t) == 0)
+ {
+ if (ECHO_IS_ON(t))
+ {
+ TURN_ECHO_OFF(t);
+ echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
+ TURN_ECHO_ON(t);
+ }
+ else
+ echo_off = 0;
+ }
+ else
+ echo_off = 0;
+
+ /* Write the prompt. */
+ fputs (prompt, out);
+ fflush (out);
+
+ /* Read the password. */
+ buf[0] = 0;
+ fgets(buf, bufsize, in);
+ nread = strlen(buf);
+ if (buf[nread - 1] == '\n')
+ buf[nread - 1] = '\0';
+
+ /* Restore echoing. */
+ if (echo_off)
+ (void) tcsetattr (fileno (in), 0, &t);
+
+ if (in != stdin)
+ /* We opened the terminal; now close it. */
+ fclose (in);
+
+ /* Catch problematic signals */
+ signal(SIGINT, SIGNAL_CAST SIG_DFL);
+
+ printf("\n");
+ return buf;
+}
+
+#else
+
+void getsmbpasswd_dummy() {;}
+#endif
diff -u -r --new-file last-version/source/ipc.c samba-1.9.14alpha13/source/ipc.c
--- last-version/source/ipc.c Sat Sep 2 17:44:54 1995
+++ samba-1.9.14alpha13/source/ipc.c Sun Sep 10 23:09:50 1995
@@ -529,7 +529,7 @@
DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",SERVICE(snum),count));
}
-static BOOL api_DosPrintQGetInfo(int cnum,char *param,char *data,
+static BOOL api_DosPrintQGetInfo(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -596,7 +596,7 @@
/****************************************************************************
view list of all print jobs on all queues
****************************************************************************/
-static BOOL api_DosPrintQEnum(int cnum, char* param, char* data,
+static BOOL api_DosPrintQEnum(int cnum, int uid, char* param, char* data,
int mdrcnt, int mprcnt,
char **rdata, char** rparam,
int *rdata_len, int *rparam_len)
@@ -789,7 +789,7 @@
return len;
}
-static BOOL api_RNetShareGetInfo(int cnum,char *param,char *data,
+static BOOL api_RNetShareGetInfo(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -824,7 +824,7 @@
/****************************************************************************
view list of shares available
****************************************************************************/
-static BOOL api_RNetShareEnum(int cnum,char *param,char *data,
+static BOOL api_RNetShareEnum(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -888,7 +888,7 @@
/****************************************************************************
get the time of day info
****************************************************************************/
-static BOOL api_NetRemoteTOD(int cnum,char *param,char *data,
+static BOOL api_NetRemoteTOD(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -932,7 +932,7 @@
/****************************************************************************
set the user password
****************************************************************************/
-static BOOL api_SetUserPassword(int cnum,char *param,char *data,
+static BOOL api_SetUserPassword(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -958,7 +958,8 @@
DEBUG(3,("Set password for <%s>\n",user));
- if (!password_ok(user,pass1,strlen(pass1),NULL) || !chgpasswd(user,pass1,pass2))
+ if (!password_ok(user,pass1,strlen(pass1),NULL) ||
+ !chgpasswd(user,pass1,pass2))
SSVAL(*rparam,0,NERR_badpass);
bzero(pass1,sizeof(fstring));
@@ -971,7 +972,7 @@
delete a print job
Form: <W> <>
****************************************************************************/
-static BOOL api_RDosPrintJobDel(int cnum,char *param,char *data,
+static BOOL api_RDosPrintJobDel(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1018,7 +1019,7 @@
return(True);
}
-static BOOL api_WPrintQueuePurge(int cnum,char *param,char *data,
+static BOOL api_WPrintQueuePurge(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1071,7 +1072,7 @@
/****************************************************************************
set the name of a print job (undocumented?)
****************************************************************************/
-static BOOL api_PrintJobInfo(int cnum,char *param,char *data,
+static BOOL api_PrintJobInfo(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1111,7 +1112,7 @@
GetWd(wd);
unbecome_user();
- if (!become_user(Files[i].cnum) || !become_service(Files[i].cnum,True))
+ if (!become_user(Files[i].cnum,uid) || !become_service(Files[i].cnum,True))
break;
if (rename(Files[i].name,name) == 0)
@@ -1137,7 +1138,7 @@
#define SV_TYPE_AFP 0x00000040
#define SV_TYPE_NOVELL 0x00000080
-static BOOL api_RNetServerGetInfo(int cnum,char *param,char *data,
+static BOOL api_RNetServerGetInfo(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1221,7 +1222,7 @@
/****************************************************************************
get info about the server
****************************************************************************/
-static BOOL api_NetWkstaGetInfo(int cnum,char *param,char *data,
+static BOOL api_NetWkstaGetInfo(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1296,7 +1297,7 @@
#define USER_PRIV_USER 1
#define USER_PRIV_ADMIN 2
-static BOOL api_RNetUserGetInfo(int cnum,char *param,char *data,
+static BOOL api_RNetUserGetInfo(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1417,7 +1418,7 @@
return(True);
}
-static BOOL api_WWkstaUserLogon(int cnum,char *param,char *data,
+static BOOL api_WWkstaUserLogon(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1478,7 +1479,7 @@
/****************************************************************************
api_WAccessGetUserPerms
****************************************************************************/
-static BOOL api_WAccessGetUserPerms(int cnum,char *param,char *data,
+static BOOL api_WAccessGetUserPerms(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1522,7 +1523,7 @@
return True;
}
-static BOOL api_WPrintJobGetInfo(int cnum,char *param,char *data,
+static BOOL api_WPrintJobGetInfo(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1581,7 +1582,7 @@
return(True);
}
-static BOOL api_WPrintJobEnumerate(int cnum,char *param,char *data,
+static BOOL api_WPrintJobEnumerate(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1691,7 +1692,7 @@
}
}
-static BOOL api_WPrintDestGetInfo(int cnum,char *param,char *data,
+static BOOL api_WPrintDestGetInfo(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1747,7 +1748,7 @@
return(True);
}
-static BOOL api_WPrintDestEnum(int cnum,char *param,char *data,
+static BOOL api_WPrintDestEnum(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1802,7 +1803,7 @@
return(True);
}
-static BOOL api_WPrintDriverEnum(int cnum,char *param,char *data,
+static BOOL api_WPrintDriverEnum(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1844,7 +1845,7 @@
return(True);
}
-static BOOL api_WPrintQProcEnum(int cnum,char *param,char *data,
+static BOOL api_WPrintQProcEnum(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1886,7 +1887,7 @@
return(True);
}
-static BOOL api_WPrintPortEnum(int cnum,char *param,char *data,
+static BOOL api_WPrintPortEnum(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1931,7 +1932,7 @@
/****************************************************************************
the buffer was too small
****************************************************************************/
-static BOOL api_TooSmall(int cnum,char *param,char *data,
+static BOOL api_TooSmall(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -1952,7 +1953,7 @@
/****************************************************************************
the request is not supported
****************************************************************************/
-static BOOL api_Unsupported(int cnum,char *param,char *data,
+static BOOL api_Unsupported(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
@@ -2007,7 +2008,7 @@
/****************************************************************************
handle remote api calls
****************************************************************************/
-static int api_reply(int cnum,char *outbuf,char *data,char *params,
+static int api_reply(int cnum,int uid,char *outbuf,char *data,char *params,
int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
{
int api_command = SVAL(params,0);
@@ -2032,21 +2033,21 @@
rdata = (char *)malloc(1024); if (rdata) bzero(rdata,1024);
rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
- reply = api_commands[i].fn(cnum,params,data,mdrcnt,mprcnt,
+ reply = api_commands[i].fn(cnum,uid,params,data,mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
if (rdata_len > mdrcnt ||
rparam_len > mprcnt)
{
- reply = api_TooSmall(cnum,params,data,mdrcnt,mprcnt,
+ reply = api_TooSmall(cnum,uid,params,data,mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
}
/* if we get False back then it's actually unsupported */
if (!reply)
- api_Unsupported(cnum,params,data,mdrcnt,mprcnt,
+ api_Unsupported(cnum,uid,params,data,mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
@@ -2065,14 +2066,14 @@
/****************************************************************************
handle named pipe commands
****************************************************************************/
-static int named_pipe(int cnum,char *outbuf,char *name,
+static int named_pipe(int cnum,int uid, char *outbuf,char *name,
uint16 *setup,char *data,char *params,
int suwcnt,int tdscnt,int tpscnt,
int msrcnt,int mdrcnt,int mprcnt)
{
if (strequal(name,"LANMAN"))
- return(api_reply(cnum,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt));
+ return(api_reply(cnum,uid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt));
DEBUG(3,("named pipe command on <%s> 0x%X setup1=%d\n",
name,(int)setup[0],(int)setup[1]));
@@ -2093,6 +2094,7 @@
int outsize = 0;
int cnum = SVAL(inbuf,smb_tid);
+ int uid = SVAL(inbuf,smb_uid);
int tpscnt = SVAL(inbuf,smb_vwv0);
int tdscnt = SVAL(inbuf,smb_vwv1);
@@ -2181,7 +2183,7 @@
if (strncmp(name,"\\PIPE\\",strlen("\\PIPE\\")) == 0)
- outsize = named_pipe(cnum,outbuf,name+strlen("\\PIPE\\"),setup,data,params,
+ outsize = named_pipe(cnum,uid,outbuf,name+strlen("\\PIPE\\"),setup,data,params,
suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt);
@@ -2190,7 +2192,7 @@
if (setup) free(setup);
if (close_on_completion)
- close_cnum(cnum);
+ close_cnum(cnum,uid);
if (one_way)
return(-1);
diff -u -r --new-file last-version/source/password.c samba-1.9.14alpha13/source/password.c
--- last-version/source/password.c Sat Sep 2 14:51:59 1995
+++ samba-1.9.14alpha13/source/password.c Sun Sep 10 23:10:06 1995
@@ -31,7 +31,7 @@
#ifdef SMB_PASSWD
/* Data to do lanman1/2 password challenge. */
static unsigned char saved_challenge[8];
-static int challenge_sent=0;
+static BOOL challenge_sent=False;
/*******************************************************************
Get the next challenge value - no repeats.
@@ -49,7 +49,7 @@
SIVAL(challenge,4,v2);
E1(challenge,"SAMBA",saved_challenge);
memcpy(challenge,saved_challenge,8);
- challenge_sent = 4;
+ challenge_sent = True;
}
/*******************************************************************
@@ -59,7 +59,7 @@
{
if (!challenge_sent) return(False);
memcpy(challenge,saved_challenge,8);
- challenge_sent--;
+/* challenge_sent = False; */
return(True);
}
#endif
@@ -86,6 +86,19 @@
}
/****************************************************************************
+check if a uid has been validated, and return an pointer to the user_struct
+if it has. NULL if not
+****************************************************************************/
+
+user_struct *get_valid_user_struct(int uid)
+{
+ int vuid = valid_uid(uid);
+ if(vuid == -1)
+ return NULL;
+ return &validated_users[vuid];
+}
+
+/****************************************************************************
invalidate a uid
****************************************************************************/
void invalidate_uid(int uid)
@@ -93,7 +106,18 @@
int i;
for (i=0;i<num_validated_users;i++)
if (validated_users[i].uid == uid)
- validated_users[i].uid = -1;
+ {
+ user_struct *vuser = &validated_users[i];
+ vuser->uid = -1;
+ vuser->gid = -1;
+ vuser->user_ngroups = 0;
+ if(vuser->user_groups && (vuser->user_groups != (gid_t *)vuser->user_igroups))
+ free(vuser->user_groups);
+ vuser->user_groups = NULL;
+ if(vuser->user_igroups)
+ free(vuser->user_igroups);
+ vuser->user_igroups = NULL;
+ }
return;
}
@@ -111,8 +135,10 @@
register a uid/name pair as being valid and that a valid password
has been given.
****************************************************************************/
-void register_uid(int uid,char *name,BOOL guest)
+void register_uid(int uid,int gid, char *name,BOOL guest)
{
+ user_struct *vuser;
+
if (valid_uid(uid) >= 0)
return;
validated_users = (user_struct *)Realloc(validated_users,
@@ -125,9 +151,18 @@
return;
}
- validated_users[num_validated_users].uid = uid;
- validated_users[num_validated_users].guest = guest;
- strcpy(validated_users[num_validated_users].name,name);
+ vuser = &validated_users[num_validated_users];
+ vuser->uid = uid;
+ vuser->gid = gid;
+ vuser->guest = guest;
+ strcpy(vuser->name,name);
+
+ vuser->user_ngroups = 0;
+ vuser->user_groups = NULL;
+ vuser->user_igroups = NULL;
+
+ /* Find all the groups this uid is in and store them. Used by become_user() */
+ setup_groups(name,uid,gid,&vuser->user_ngroups,&vuser->user_igroups,&vuser->user_groups);
DEBUG(3,("uid %d registered to name %s\n",uid,name));
@@ -577,9 +612,12 @@
pass = Get_Pwnam(user,True);
#ifdef SMB_PASSWD
+
+ DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done));
+
if((pwlen == 24) && challenge_done)
{
- DEBUG(4,("Checking password for user %s (l=24)\n",user));
+ DEBUG(4,("Checking SMB password for user %s (l=24)\n",user));
if (!pass)
{
@@ -606,6 +644,8 @@
update_protected_database(user,True);
return(True);
}
+
+ DEBUG(3,("Error smb_password_check failed\n"));
}
#endif
@@ -776,7 +816,8 @@
setnetgrent(group);
while (getnetgrent(&host, &user, &domain)) {
if (user) {
- if (user_ok(user, snum) && password_ok(user,password,NULL)) {
+ if (user_ok(user, snum) &&
+ password_ok(user,password,pwlen,NULL)) {
endnetgrent();
return(user);
}
@@ -811,7 +852,7 @@
while (pwd = getpwent ()) {
if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
/* This Entry have PASSWORD and same GID then check pwd */
- if (password_ok(0, password, pwlen, pwd)) {
+ if (password_ok(NULL, password, pwlen, pwd)) {
strcpy(tm, pwd->pw_name);
endpwent ();
return tm;
@@ -941,7 +982,8 @@
{
fstring user2;
strcpy(user2,auser);
- if (user_ok(user2,snum) && password_ok(user2,password,pwlen,NULL))
+ if (user_ok(user2,snum) &&
+ password_ok(user2,password,pwlen,NULL))
{
ok = True;
strcpy(user,user2);
diff -u -r --new-file last-version/source/reply.c samba-1.9.14alpha13/source/reply.c
--- last-version/source/reply.c Tue Jul 11 14:41:21 1995
+++ samba-1.9.14alpha13/source/reply.c Sun Sep 10 23:10:16 1995
@@ -175,7 +175,7 @@
/* we might have to close an old one */
if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0)
- close_cnum(SVAL(inbuf,smb_tid));
+ close_cnum(SVAL(inbuf,smb_tid),uid);
vuid = valid_uid(uid);
@@ -276,6 +276,7 @@
{
int outsize = 0;
int sess_uid;
+ int gid;
int smb_com2;
int smb_off2;
int smb_bufsize;
@@ -395,6 +396,17 @@
/* perhaps grab OS version here?? */
}
+/* Set the correct uid in the outgoing and incoming packets
+ We will use this on future requests to determine which
+ user we should become.
+*/
+ {
+ struct passwd *pw = Get_Pwnam(user,False);
+ gid = pw->pw_gid;
+ SSVAL(outbuf,smb_uid,(uint16)pw->pw_uid);
+ SSVAL(inbuf,smb_uid,(uint16)pw->pw_uid);
+ }
+
CVAL(outbuf,smb_vwv0) = smb_com2;
SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
@@ -403,8 +415,8 @@
/* register the name and uid as being validated, so further connections
to a uid can get through without a password, on the same VC */
- register_uid(SVAL(inbuf,smb_uid),user,guest);
-
+ register_uid(SVAL(inbuf,smb_uid),gid,user,guest);
+
maxxmit = MIN(maxxmit,smb_bufsize);
if (smb_com2 != 0xFF)
@@ -2012,14 +2024,15 @@
****************************************************************************/
int reply_tdis(char *inbuf,char *outbuf)
{
- int cnum;
+ int cnum, uid;
int outsize = set_message(outbuf,0,0,True);
cnum = SVAL(inbuf,smb_tid);
+ uid = SVAL(inbuf,smb_uid);
Connections[cnum].used = False;
- close_cnum(cnum);
+ close_cnum(cnum,uid);
DEBUG(3,("%s tdis cnum=%d\n",timestring(),cnum));
@@ -2164,12 +2177,13 @@
****************************************************************************/
int reply_printqueue(char *inbuf,char *outbuf)
{
- int cnum;
+ int cnum, uid;
int outsize = set_message(outbuf,2,3,True);
int max_count = SVAL(inbuf,smb_vwv0);
int start_index = SVAL(inbuf,smb_vwv1);
cnum = SVAL(inbuf,smb_tid);
+ uid = SVAL(inbuf,smb_uid);
/* allow checking the queue for anyone */
#if 0
@@ -2205,7 +2219,7 @@
DEBUG(5,("connection not open or not a printer, using cnum %d\n",cnum));
}
- if (!become_user(cnum))
+ if (!become_user(cnum,uid))
return(ERROR(ERRSRV,ERRinvnid));
{
diff -u -r --new-file last-version/source/server.c samba-1.9.14alpha13/source/server.c
--- last-version/source/server.c Sat Sep 2 13:25:03 1995
+++ samba-1.9.14alpha13/source/server.c Sun Sep 10 23:17:14 1995
@@ -552,7 +552,8 @@
return;
}
- /* this handles a bug in Win95 - it doesn't say to create the file when it should */
+ /* this handles a bug in Win95 - it doesn't say to create the file when it
+ should */
if (Connections[cnum].printer)
flags |= O_CREAT;
@@ -891,8 +892,10 @@
open_mode = 0;
}
- open_file(fnum,cnum,fname,flags|flags2,mode);
- if (!Files[fnum].open && flags==O_RDWR && errno!=ENOENT) {
+ DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X\n",flags,flags2));
+
+ open_file(fnum,cnum,fname,flags|flags2,mode);
+ if (!Files[fnum].open && flags==O_RDWR) {
flags = O_RDONLY;
*Access = 0;
open_mode = 0;
@@ -1238,15 +1241,18 @@
/****************************************************************************
become the user of a connection number
****************************************************************************/
-BOOL become_user(int cnum)
+BOOL become_user(int cnum, int uid)
{
+ user_struct *vuser;
+ int snum;
+
if (!OPEN_CNUM(cnum))
{
DEBUG(2,("Connection %d not open\n",cnum));
return(False);
}
- if (done_become_user == cnum)
+ if (done_become_user == uid)
{
DEBUG(4,("Skipping become_user - already user\n"));
return(True);
@@ -1254,27 +1260,66 @@
if (done_become_user != -1)
unbecome_user();
-
- if (initial_uid == 0)
- {
- if (!become_gid(Connections[cnum].gid))
- return(False);
- if (!IS_IPC(cnum))
- {
+ snum = Connections[cnum].service;
+
+ /* Check if the user id given has been validated
+ If so, become that user, else become the opener
+ of the connection.
+ *** NOTE *** SHOULD THIS JUST FAIL INSTEAD if get_valid_user_struct
+ returns NULL ?????
+ */
+ if(!(*lp_force_user(snum)) && (vuser = get_valid_user_struct(uid)))
+ {
+ DEBUG(5,("got valid user_struct for uid %d\n", uid));
+ if (initial_uid == 0)
+ {
+ int gid_to_become;
+ if(!*lp_force_group(snum))
+ gid_to_become = vuser->gid;
+ else
+ gid_to_become = Connections[cnum].gid;
+
+ if (!become_gid(gid_to_become))
+ return(False);
+
+ if (!IS_IPC(cnum))
+ {
/* groups stuff added by ih/wreu */
- if (Connections[cnum].ngroups > 0)
- if (setgroups(Connections[cnum].ngroups,(GID_TYPE *)Connections[cnum].groups)<0)
+ if (vuser->user_ngroups > 0)
+ if (setgroups(vuser->user_ngroups,(GID_TYPE *)vuser->user_groups)<0)
DEBUG(0,("setgroups call failed!\n"));
+ }
+
+ if (!Connections[cnum].admin_user && !become_uid(vuser->uid))
+ return(False);
}
+ }
+ else
+ {
+ uid = Connections[cnum].uid; /* Set this so done_become_user is set correctly */
- if (!Connections[cnum].admin_user && !become_uid(Connections[cnum].uid))
- return(False);
+ if (initial_uid == 0)
+ {
+ if (!become_gid(Connections[cnum].gid))
+ return(False);
+
+ if (!IS_IPC(cnum))
+ {
+ /* groups stuff added by ih/wreu */
+ if (Connections[cnum].ngroups > 0)
+ if (setgroups(Connections[cnum].ngroups,(GID_TYPE *)Connections[cnum].groups)<0)
+ DEBUG(0,("setgroups call failed!\n"));
+ }
+
+ if (!Connections[cnum].admin_user && !become_uid(Connections[cnum].uid))
+ return(False);
+ }
}
old_umask = umask(0777 & ~(CREATE_MODE(cnum)));
- done_become_user = cnum;
+ done_become_user = uid;
DEBUG(5,("become_user now uid=(%d,%d) gid=(%d,%d)\n",
getuid(),geteuid(),getgid(),getegid()));
@@ -1836,6 +1881,71 @@
return(0);
}
+/****************************************************************************
+Setup the groups a user belongs to.
+****************************************************************************/
+int setup_groups(char *user, int uid, int gid, int *p_ngroups, int **p_igroups, GID_TYPE **p_groups)
+{
+ if (-1 == initgroups(user,gid))
+ {
+ if (getuid() == 0)
+ {
+ DEBUG(0,("Unable to initgroups!\n"));
+ if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
+ DEBUG(0,("This is probably a problem with the account %s\n",user));
+ }
+ }
+ else
+ {
+ int i,ngroups;
+ int *igroups;
+ GID_TYPE grp = 0;
+ ngroups = getgroups(0,&grp);
+ if (ngroups <= 0)
+ ngroups = 32;
+ igroups = (int *)malloc(sizeof(int)*ngroups);
+ for (i=0;i<ngroups;i++)
+ igroups[i] = 0x42424242;
+ ngroups = getgroups(ngroups,(GID_TYPE *)igroups);
+
+ if (igroups[0] == 0x42424242)
+ ngroups = 0;
+
+ *p_ngroups = ngroups;
+
+ /* The following bit of code is very strange. It is due to the
+ fact that some OSes use int* and some use gid_t* for
+ getgroups, and some (like SunOS) use both, one in prototypes,
+ and one in man pages and the actual code. Thus we detect it
+ dynamically using some very ugly code */
+ if (ngroups > 0)
+ {
+ for (i=0;i<ngroups;i++)
+ if (igroups[i] == 0x42424242)
+ groups_use_ints = False;
+
+ if (groups_use_ints)
+ {
+ *p_igroups = igroups;
+ *p_groups = (gid_t *)igroups;
+ }
+ else
+ {
+ gid_t *groups = (gid_t *)igroups;
+ igroups = (int *)malloc(sizeof(int)*ngroups);
+ for (i=0;i<ngroups;i++)
+ igroups[i] = groups[i];
+ *p_igroups = igroups;
+ *p_groups = groups;
+ }
+ }
+ DEBUG(3,("%s is in %d groups\n",user,ngroups));
+ for (i=0;i<ngroups;i++)
+ DEBUG(3,("%d ",igroups[i]));
+ DEBUG(3,("\n"));
+ }
+ return 0;
+}
/****************************************************************************
make a connection to a service
@@ -1845,6 +1955,7 @@
int cnum;
int snum;
struct passwd *pass = NULL;
+ connection_struct *pcon;
BOOL guest = False;
static BOOL first_connection = True;
@@ -1915,6 +2026,8 @@
return(-1);
}
+ pcon = &Connections[cnum];
+
/* find out some info about the user */
pass = Get_Pwnam(user,True);
@@ -1924,36 +2037,36 @@
return(-1);
}
- Connections[cnum].read_only = lp_readonly(snum);
+ pcon->read_only = lp_readonly(snum);
if (user_in_list(user,lp_readlist(snum)))
- Connections[cnum].read_only = True;
+ pcon->read_only = True;
if (user_in_list(user,lp_writelist(snum)))
- Connections[cnum].read_only = False;
+ pcon->read_only = False;
/* admin user check */
if (user_in_list(user,lp_admin_users(snum)) &&
- !Connections[cnum].read_only)
+ !pcon->read_only)
{
- Connections[cnum].admin_user = True;
+ pcon->admin_user = True;
DEBUG(0,("%s logged in as admin user (root privilages)\n",user));
}
else
- Connections[cnum].admin_user = False;
+ pcon->admin_user = False;
- Connections[cnum].uid = pass->pw_uid;
- Connections[cnum].gid = pass->pw_gid;
- Connections[cnum].num_files_open = 0;
- Connections[cnum].lastused = time(NULL);
- Connections[cnum].service = snum;
- Connections[cnum].used = True;
- Connections[cnum].printer = (strncmp(dev,"LPT",3) == 0);
- Connections[cnum].ipc = (strncmp(dev,"IPC",3) == 0);
- Connections[cnum].dirptr = NULL;
- string_set(&Connections[cnum].dirpath,"");
- string_set(&Connections[cnum].user,user);
+ pcon->uid = pass->pw_uid;
+ pcon->gid = pass->pw_gid;
+ pcon->num_files_open = 0;
+ pcon->lastused = time(NULL);
+ pcon->service = snum;
+ pcon->used = True;
+ pcon->printer = (strncmp(dev,"LPT",3) == 0);
+ pcon->ipc = (strncmp(dev,"IPC",3) == 0);
+ pcon->dirptr = NULL;
+ string_set(&pcon->dirpath,"");
+ string_set(&pcon->user,user);
#if HAVE_GETGRNAM
if (*lp_force_group(snum))
@@ -1961,7 +2074,7 @@
struct group *gptr = (struct group *)getgrnam(lp_force_group(snum));
if (gptr)
{
- Connections[cnum].gid = gptr->gr_gid;
+ pcon->gid = gptr->gr_gid;
DEBUG(3,("Forced group %s\n",lp_force_group(snum)));
}
else
@@ -1977,8 +2090,8 @@
pass2 = (struct passwd *)Get_Pwnam(fuser,True);
if (pass2)
{
- Connections[cnum].uid = pass2->pw_uid;
- string_set(&Connections[cnum].user,fuser);
+ pcon->uid = pass2->pw_uid;
+ string_set(&pcon->user,fuser);
strcpy(user,fuser);
DEBUG(3,("Forced user %s\n",fuser));
}
@@ -1990,79 +2103,19 @@
pstring s;
strcpy(s,lp_pathname(snum));
standard_sub(cnum,s);
- string_set(&Connections[cnum].connectpath,s);
+ string_set(&pcon->connectpath,s);
DEBUG(3,("Connect path is %s\n",s));
}
/* groups stuff added by ih */
- Connections[cnum].ngroups = 0;
- Connections[cnum].groups = NULL;
+ pcon->ngroups = 0;
+ pcon->groups = NULL;
if (!IS_IPC(cnum))
{
-
- if (-1 == initgroups(Connections[cnum].user,Connections[cnum].gid))
- {
- if (getuid() == 0)
- {
- DEBUG(0,("Unable to initgroups!\n"));
- if (Connections[cnum].gid < 0 || Connections[cnum].gid > 16000 ||
- Connections[cnum].uid < 0 || Connections[cnum].uid > 16000)
- DEBUG(0,("This is probably a problem with the account %s\n",
- Connections[cnum].user));
- }
- }
- else
- {
- int i,ngroups;
- int *igroups;
- GID_TYPE grp = 0;
- ngroups = getgroups(0,&grp);
- if (ngroups <= 0)
- ngroups = 32;
- igroups = (int *)malloc(sizeof(int)*ngroups);
- for (i=0;i<ngroups;i++)
- igroups[i] = 0x42424242;
- ngroups = getgroups(ngroups,(GID_TYPE *)igroups);
-
- if (igroups[0] == 0x42424242)
- ngroups = 0;
-
- Connections[cnum].ngroups = ngroups;
-
- /* The following bit of code is very strange. It is due to the
- fact that some OSes use int* and some use gid_t* for
- getgroups, and some (like SunOS) use both, one in prototypes,
- and one in man pages and the actual code. Thus we detect it
- dynamically using some very ugly code */
- if (ngroups > 0)
- {
- for (i=0;i<ngroups;i++)
- if (igroups[i] == 0x42424242)
- groups_use_ints = False;
-
- if (groups_use_ints)
- {
- Connections[cnum].igroups = igroups;
- Connections[cnum].groups = (gid_t *)igroups;
- }
- else
- {
- gid_t *groups = (gid_t *)igroups;
- igroups = (int *)malloc(sizeof(int)*ngroups);
- for (i=0;i<ngroups;i++)
- igroups[i] = groups[i];
- Connections[cnum].igroups = igroups;
- Connections[cnum].groups = groups;
- }
- }
- DEBUG(3,("%s is in %d groups\n",Connections[cnum].user,ngroups));
- for (i=0;i<ngroups;i++)
- DEBUG(3,("%d ",igroups[i]));
- DEBUG(3,("\n"));
- }
-
-
+ /* Find all the groups this uid is in and store them. Used by become_user() */
+ setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
+
/* check number of connections */
if (!claim_connection(cnum,
lp_servicename(SNUM(cnum)),
@@ -2078,7 +2131,7 @@
first_connection = False;
} /* IS_IPC */
- Connections[cnum].open = True;
+ pcon->open = True;
/* execute any "root preexec = " line */
if (*lp_rootpreexec(SNUM(cnum)))
@@ -2090,30 +2143,30 @@
smbrun(cmd,NULL);
}
- if (!become_user(cnum))
+ if (!become_user(cnum,pcon->uid))
{
DEBUG(0,("Can't become connected user!\n"));
- Connections[cnum].open = False;
+ pcon->open = False;
return(-1);
}
- if (ChDir(Connections[cnum].connectpath) != 0)
+ if (ChDir(pcon->connectpath) != 0)
{
- DEBUG(0,("Can't change directory to %s\n",Connections[cnum].connectpath));
- Connections[cnum].open = False;
+ DEBUG(0,("Can't change directory to %s\n",pcon->connectpath));
+ pcon->open = False;
return(-1);
}
- string_set(&Connections[cnum].origpath,Connections[cnum].connectpath);
+ string_set(&pcon->origpath,pcon->connectpath);
#if SOFTLINK_OPTIMISATION
/* resolve any soft links early */
{
pstring s;
- strcpy(s,Connections[cnum].connectpath);
+ strcpy(s,pcon->connectpath);
GetWd(s);
- string_set(&Connections[cnum].connectpath,s);
- ChDir(Connections[cnum].connectpath);
+ string_set(&pcon->connectpath,s);
+ ChDir(pcon->connectpath);
}
#endif
@@ -2139,8 +2192,8 @@
timestring(),
Client_info.name,Client_info.addr,
lp_servicename(SNUM(cnum)),user,
- Connections[cnum].uid,
- Connections[cnum].gid,
+ pcon->uid,
+ pcon->gid,
(int)getpid()));
}
@@ -2804,7 +2857,7 @@
/****************************************************************************
close a cnum
****************************************************************************/
-void close_cnum(int cnum)
+void close_cnum(int cnum, int uid)
{
extern struct from_host Client_info;
@@ -2832,7 +2885,7 @@
dptr_closecnum(cnum);
/* execute any "postexec = " line */
- if (*lp_postexec(SNUM(cnum)) && become_user(cnum))
+ if (*lp_postexec(SNUM(cnum)) && become_user(cnum,uid))
{
pstring cmd;
strcpy(cmd,lp_postexec(SNUM(cnum)));
@@ -3090,7 +3143,7 @@
unbecome_user();
for (i=0;i<MAX_CONNECTIONS;i++)
if (Connections[i].open)
- close_cnum(i);
+ close_cnum(i,-1);
if (!reason) {
int oldlevel = DEBUGLEVEL;
DEBUGLEVEL = 10;
@@ -3323,13 +3376,14 @@
{
int cnum = SVAL(inbuf,smb_tid);
int flags = smb_messages[match].flags;
+ int uid = SVAL(inbuf,smb_uid);
/* does this protocol need to be run as root? */
if (!(flags & AS_USER) && (done_become_user != -1))
unbecome_user();
/* does this protocol need to be run as the connected user? */
- if ((flags & AS_USER) && !become_user(cnum))
+ if ((flags & AS_USER) && !become_user(cnum,uid))
return(ERROR(ERRSRV,ERRinvnid));
/* does it need write permission? */
diff -u -r --new-file last-version/source/smb.h samba-1.9.14alpha13/source/smb.h
--- last-version/source/smb.h Sat Sep 2 14:05:17 1995
+++ samba-1.9.14alpha13/source/smb.h Sun Sep 10 23:10:31 1995
@@ -251,8 +251,8 @@
typedef struct
{
int service;
- int uid;
- int gid;
+ int uid; /* uid of user who *opened* this connection */
+ int gid; /* gid of user who *opened* this connection */
void *dirptr;
BOOL open;
BOOL printer;
@@ -262,8 +262,9 @@
char *dirpath;
char *connectpath;
char *origpath;
- char *user;
+ char *user; /* name of user who *opened* this connection */
/* following groups stuff added by ih */
+ /* This groups info is valid for the user that *opened* the connection */
int ngroups;
gid_t *groups;
int *igroups; /* an integer version - some OSes are broken :-( */
@@ -275,9 +276,15 @@
typedef struct
{
- int uid;
- fstring name;
+ int uid; /* uid of a validated user */
+ int gid; /* gid of a validated user */
+ fstring name; /* name of a validated user */
BOOL guest;
+ /* following groups stuff added by ih */
+ /* This groups info is needed for when we become_user() for this uid */
+ int user_ngroups;
+ gid_t *user_groups;
+ int *user_igroups; /* an integer version - some OSes are broken :-( */
} user_struct;
@@ -635,6 +642,7 @@
BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
int get_printqueue(int snum,int cnum,print_queue_struct **queue,print_status_struct *status);
void parse_connect(char *buf,char *service,char *user,char *password,int *pwlen,char *dev);
+int setup_groups(char *user,int uid, int gid, int *p_ngroups, int **p_igroups, GID_TYPE **p_groups);
int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid);
char *dptr_path(int key);
char *dptr_wcard(int key);
@@ -658,8 +666,9 @@
BOOL authorise_login(int snum,char *user,char *password, int pwlen, BOOL *guest,int vuid);
void add_session_user(char *user);
int valid_uid(int uid);
+user_struct *get_valid_user_struct(int uid);
BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd);
-void register_uid(int uid,char *name,BOOL guest);
+void register_uid(int uid,int gid,char *name,BOOL guest);
BOOL fromhost(int sock,struct from_host *f);
BOOL strhasupper(char *s);
BOOL strhaslower(char *s);
@@ -713,7 +722,7 @@
BOOL receive_smb(char *buffer,int timeout);
void show_msg(char *buf);
BOOL big_endian(void );
-BOOL become_user(int cnum);
+BOOL become_user(int cnum, int uid);
BOOL unbecome_user(void);
void become_daemon(void);
BOOL reduce_name(char *s,char *dir,BOOL widelinks);
@@ -758,7 +767,7 @@
#endif
BOOL check_hosts_equiv(char *user);
int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
-void close_cnum(int cnum);
+void close_cnum(int cnum,int uid);
char *smb_errstr(char *inbuf);
void GetTimeOfDay(struct timeval *tval);
struct tm *LocalTime(time_t *t,int);
diff -u -r --new-file last-version/source/smbpass.c samba-1.9.14alpha13/source/smbpass.c
--- last-version/source/smbpass.c Tue Jul 11 20:53:22 1995
+++ samba-1.9.14alpha13/source/smbpass.c Sun Sep 10 23:10:41 1995
@@ -26,7 +26,58 @@
extern int DEBUGLEVEL;
+int gotalarm;
+void gotalarm_sig()
+{
+ gotalarm = 1;
+}
+
+int do_pw_lock(int fd, int waitsecs, int type)
+{
+ struct flock lock;
+ int ret;
+
+ gotalarm = 0;
+ signal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 1;
+ lock.l_pid = 0;
+
+ alarm(5);
+ ret = fcntl(fd, F_SETLKW, &lock);
+ alarm(0);
+ signal( SIGALRM, SIGNAL_CAST SIG_DFL);
+
+ if(gotalarm) {
+ DEBUG(0,("do_pw_lock: failed to %s SMB passwd file.\n",
+ type == F_UNLCK ? "unlock" : "lock" ));
+ return -1;
+ }
+ return ret;
+}
+
+int pw_file_lock(const char *name, int type, int secs)
+{
+ int fd = open(name,O_RDWR|O_CREAT,0666);
+ if (fd < 0) return(-1);
+ if(do_pw_lock(fd, secs, type))
+ {
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int pw_file_unlock(int fd)
+{
+ do_pw_lock(fd, 5, F_UNLCK);
+ return close(fd);
+}
+
/*
* Routine to search the smbpasswd file for an
* entry matching the username.
@@ -38,6 +89,7 @@
static pstring user_name;
static unsigned char smbpwd[16];
char linebuf[256];
+ char readbuf[16*1024];
unsigned char c;
unsigned char *p;
long uidval;
@@ -62,8 +114,11 @@
DEBUG(0,("get_smbpwnam: unable to open file %s\n", pfile));
return NULL;
}
-
- if((lockfd = file_lock(pfile,5))<0) {
+
+ /* Set a 16k buffer to do more efficient reads */
+ setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
+
+ if((lockfd = pw_file_lock(pfile,F_RDLCK,5))<0) {
DEBUG(0,("get_smbpwnam: unable to lock file %s\n", pfile));
fclose(fp);
return NULL;
@@ -83,7 +138,7 @@
if(ferror(fp))
{
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
return NULL;
}
@@ -142,7 +197,7 @@
if(!isdigit(*p)) {
DEBUG(0,("get_smbpwnam: malformed password entry (uid not number)\n"));
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
return NULL;
}
@@ -151,7 +206,7 @@
if(*p != ':') {
DEBUG(0,("get_smbpwnam: malformed password entry (no : after uid)\n"));
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
return NULL;
}
@@ -164,24 +219,24 @@
/* Password deliberately invalid - end here. */
DEBUG(10,("get_smbpwnam: entry invalidated for user %s\n",user_name));
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
return NULL;
}
if(linebuf_len < (PTR_DIFF(p,linebuf) + 33)) {
DEBUG(0,("get_smbpwnam: malformed password entry (passwd too short)\n"));
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
return(False);
}
if(p[32] != ':') {
DEBUG(0,("get_smbpwnam: malformed password entry (no terminating :)\n"));
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
return NULL;
}
- if (strequal((char *)p,"NO PASSWORD")) {
+ if (!strncasecmp((char *)p,"NO PASSWORD", 11)) {
pw_buf.smb_passwd = NULL;
} else {
char *hexchars = "0123456789ABCDEF";
@@ -196,7 +251,7 @@
if (!p1 || !p2) {
DEBUG(0,("Malformed password entry (non hex chars)\n"));
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
return NULL;
}
@@ -210,14 +265,14 @@
pw_buf.smb_name = user_name;
pw_buf.smb_userid = uidval;
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
DEBUG(5,("get_smbpwname: returning passwd entry for user %s, uid %d\n",
user_name, uidval));
return &pw_buf;
}
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
return NULL;
}
#else
diff -u -r --new-file last-version/source/smbpass.h samba-1.9.14alpha13/source/smbpass.h
--- last-version/source/smbpass.h Tue Jul 11 20:08:40 1995
+++ samba-1.9.14alpha13/source/smbpass.h Sun Sep 10 23:10:47 1995
@@ -41,4 +41,7 @@
void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
+/* Password file lock/unlock routines */
+int pw_file_lock(const char *name, int type, int secs);
+int pw_file_unlock(int fd);
#endif
diff -u -r --new-file last-version/source/smbpasswd.c samba-1.9.14alpha13/source/smbpasswd.c
--- last-version/source/smbpasswd.c Tue Jul 11 20:05:24 1995
+++ samba-1.9.14alpha13/source/smbpasswd.c Sun Sep 10 23:28:28 1995
@@ -24,6 +24,11 @@
#include "includes.h"
#include "des.h"
+#ifdef SMBGETPASS
+extern char *getsmbpass(const char *);
+#define getpass getsmbpass
+#endif
+
/* Static buffers we will return. */
static struct smb_passwd pw_buf;
static pstring user_name;
@@ -121,7 +126,7 @@
if(p[32] != ':')
return(False);
- if(strequal(p,"NO PASSWORD")) {
+ if(!strncasecmp(p,"NO PASSWORD",11)) {
pw_buf.smb_passwd = NULL; /* No password */
} else {
char *hexchars = "0123456789ABCDEF";
@@ -180,6 +185,7 @@
int ret, i, err;
int lockfd=-1;
char *pfile = SMB_PASSWD_FILE;
+ char readbuf[16*1024];
charset_initialise();
@@ -261,12 +267,15 @@
perror(argv[0]);
exit(err);
}
-
+
+ /* Set read buffer to 16k for effiecient reads */
+ setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
+
/* make sure it is only rw by the owner */
chmod(pfile,0600);
/* Lock the smbpasswd file for write. */
- if((lockfd=file_lock(pfile,5))<0) {
+ if((lockfd=pw_file_lock(pfile,F_WRLCK,5))<0) {
err = errno;
fprintf(stderr, "%s: Failed to lock password file %s.\n",
argv[0], pfile);
@@ -282,7 +291,7 @@
fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
argv[0], pwd->pw_name, pfile);
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
exit(1);
}
@@ -291,7 +300,7 @@
if( valid_old_pwd == False) {
fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name);
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
exit(1);
}
/* Check the old passwd (if there was one). */
@@ -299,7 +308,7 @@
if( memcmp( old_p16, smb_pwent->smb_passwd, 16)) {
fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
exit(1);
}
}
@@ -321,7 +330,7 @@
fclose(fp);
errno = err;
perror(argv[0]);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
exit(1);
}
/* Sanity check - ensure the character is a ':' */
@@ -332,14 +341,14 @@
fclose(fp);
errno = err;
perror(argv[0]);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
exit(1);
}
if(c != ':') {
fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
argv[0], pfile);
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
exit(1);
}
if(write(pwfd,ascii_p16,32)!=32) {
@@ -349,11 +358,11 @@
fclose(fp);
errno = err;
perror(argv[0]);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
exit(err);
}
fclose(fp);
- file_unlock(lockfd);
+ pw_file_unlock(lockfd);
printf("Password changed\n");
return 0;
}
diff -u -r --new-file last-version/source/util.c samba-1.9.14alpha13/source/util.c
--- last-version/source/util.c Sat Sep 2 15:39:39 1995
+++ samba-1.9.14alpha13/source/util.c Fri Sep 8 13:04:37 1995
@@ -3322,14 +3322,18 @@
set the time on a file
****************************************************************************/
BOOL set_filetime(char *fname,time_t mtime)
-{
+{
struct utimbuf times;
if (null_mtime(mtime)) return(True);
times.modtime = times.actime = mtime;
- return(utime(fname,×) == 0);
+ if (utime(fname,×)) {
+ DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
+ }
+
+ return(True);
}
@@ -3534,6 +3538,11 @@
if (res == -1)
{ DEBUG(0,("socket failed\n")); return -1; }
+ {
+ int one=1;
+ setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
+ }
+
/* now we've got a socket - we need to bind it */
if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
{
@@ -3550,11 +3559,6 @@
return(-1);
}
DEBUG(1,("bind succeeded on port %d\n",port));
-
- {
- int one=1;
- setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
- }
return res;
}
diff -u -r --new-file last-version/source/version.h samba-1.9.14alpha13/source/version.h
--- last-version/source/version.h Sat Sep 2 18:01:06 1995
+++ samba-1.9.14alpha13/source/version.h Mon Sep 11 00:15:56 1995
@@ -1 +1 @@
-#define VERSION "1.9.14alpha12"
+#define VERSION "1.9.14alpha13"